home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 May: Tool Chest / Developer CD Series May 1996 (Tool Chest) (Apple Computer) (1996).iso / Tool Chest / Development Tools & Languages / Dylan Related / Mindy / Mindy 1.2 - portable sources / interp / weak.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-03-15  |  4.1 KB  |  164 lines  |  [TEXT/ttxt]

  1. /**********************************************************************\
  2. *
  3. *  Copyright (c) 1994  Carnegie Mellon University
  4. *  All rights reserved.
  5. *  
  6. *  Use and copying of this software and preparation of derivative
  7. *  works based on this software are permitted, including commercial
  8. *  use, provided that the following conditions are observed:
  9. *  
  10. *  1. This copyright notice must be retained in full on any copies
  11. *     and on appropriate parts of any derivative works.
  12. *  2. Documentation (paper or online) accompanying any system that
  13. *     incorporates this software, or any part of it, must acknowledge
  14. *     the contribution of the Gwydion Project at Carnegie Mellon
  15. *     University.
  16. *  
  17. *  This software is made available "as is".  Neither the authors nor
  18. *  Carnegie Mellon University make any warranty about the software,
  19. *  its performance, or its conformity to any specification.
  20. *  
  21. *  Bug reports, questions, comments, and suggestions should be sent by
  22. *  E-mail to the Internet address "gwydion-bugs@cs.cmu.edu".
  23. *
  24. ***********************************************************************
  25. *
  26. * $Header: weak.c,v 1.6 94/10/05 21:05:00 nkramer Exp $
  27. *
  28. * This file implements weak pointers.
  29. *
  30. \**********************************************************************/
  31.  
  32. #include "../compat/std-c.h"
  33.  
  34. #include "mindy.h"
  35. #include "gc.h"
  36. #include "obj.h"
  37. #include "bool.h"
  38. #include "list.h"
  39. #include "type.h"
  40. #include "class.h"
  41. #include "def.h"
  42. #include "sym.h"
  43. #include "module.h"
  44. #include "error.h"
  45. #include "thread.h"
  46. #include "func.h"
  47. #include "weak.h"
  48.  
  49.  
  50. obj_t obj_WeakPointerClass = NULL;
  51.  
  52. static struct weak_pointer *WeakPointers = NULL;
  53.  
  54. obj_t make_weak_pointer(obj_t object)
  55. {
  56.     obj_t res = alloc(obj_WeakPointerClass, sizeof(struct weak_pointer));
  57.  
  58.     WEAK(res)->object = object;
  59.     WEAK(res)->broken = FALSE;
  60.     WEAK(res)->next = NULL;
  61.  
  62.     return res;
  63. }
  64.  
  65.  
  66. /* Dylan routines. */
  67.  
  68. obj_t dylan_make_weak_pointer(obj_t class, obj_t object)
  69. {
  70.     if (object == obj_Unbound) {
  71.     error("Must supply the object when making weak pointers.");
  72.     return NULL;
  73.     }
  74.     else
  75.     return make_weak_pointer(object);
  76. }
  77.  
  78. void dylan_weak_pointer_object(obj_t meth, struct thread *thread, obj_t *args)
  79. {
  80.     obj_t weak = args[0];
  81.     obj_t *old_sp = args-1;
  82.  
  83.     old_sp[0] = WEAK(weak)->object;
  84.     old_sp[1] = WEAK(weak)->broken ? obj_True : obj_False;
  85.  
  86.     thread->sp = old_sp + 2;
  87.  
  88.     do_return(thread, old_sp, old_sp);
  89. }
  90.  
  91.  
  92.  
  93. /* GC routines. */
  94.  
  95. static int scav_weak_pointer(struct object *obj)
  96. {
  97.     struct weak_pointer *weakptr = (struct weak_pointer *)obj;
  98.  
  99.     if (!weakptr->broken && obj_is_ptr(weakptr->object)) {
  100.     weakptr->next = WeakPointers;
  101.     WeakPointers = weakptr;
  102.     }
  103.  
  104.     return sizeof(struct weak_pointer);
  105. }
  106.  
  107. static obj_t trans_weak_pointer(obj_t weakptr)
  108. {
  109.     return transport(weakptr, sizeof(struct weak_pointer));
  110. }
  111.  
  112. void scavenge_weak_roots(void)
  113. {
  114.     scavenge(&obj_WeakPointerClass);
  115.     WeakPointers = NULL;
  116. }
  117.  
  118. void break_weak_pointers(void)
  119. {
  120.     struct weak_pointer *w, *n;
  121.  
  122.     for (w = WeakPointers; w != NULL; w = n) {
  123.     if (obj_ptr(struct object *, w->object)->class == ForwardingMarker)
  124.         scavenge(&w->object);
  125.     else {
  126.         w->object = obj_False;
  127.         w->broken = TRUE;
  128.     }
  129.     n = w->next;
  130.     w->next = NULL;
  131.     }
  132. }
  133.  
  134.  
  135. /* Init stuff. */
  136.  
  137. void make_weak_classes(void)
  138. {
  139.     obj_WeakPointerClass
  140.     = make_builtin_class(scav_weak_pointer, trans_weak_pointer);
  141. }
  142.  
  143. void init_weak_classes(void)
  144. {
  145.     init_builtin_class(obj_WeakPointerClass, "<weak-pointer>", obj_ObjectClass,
  146.                NULL);
  147. }
  148.  
  149. void init_weak_functions(void)
  150. {
  151.     define_method("make", list1(singleton(obj_WeakPointerClass)), FALSE,
  152.           list1(pair(symbol("object"), obj_Unbound)),
  153.           FALSE, obj_WeakPointerClass, dylan_make_weak_pointer);
  154.     define_generic_function("weak-pointer-object", 1, FALSE, obj_False, FALSE,
  155.                 list2(obj_ObjectClass, obj_BooleanClass),
  156.                 obj_False);
  157.     add_method(find_variable(module_BuiltinStuff,symbol("weak-pointer-object"),
  158.                  FALSE, FALSE)->value,
  159.            make_raw_method("weak-pointer-object",
  160.                    list1(obj_WeakPointerClass), FALSE, obj_False,
  161.                    FALSE, list2(obj_ObjectClass, obj_BooleanClass),
  162.                    obj_False, dylan_weak_pointer_object));
  163. }
  164.